package com.example.bingobox.ui.invoke;

import android.os.Bundle;
import android.os.Environment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.bingobox.R;
import com.example.bingobox.databinding.FragmentInvokeBinding;
import com.example.bingobox.model.Invoke;
import com.example.bingobox.model.TodoBox;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.example.bingobox.view.NetworkSelector;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import java.nio.file.Files;
import java.util.Random;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.HashMap;

import com.google.android.material.dialog.MaterialAlertDialogBuilder;

public class InvokeFragment extends Fragment {

    private FragmentInvokeBinding binding;
    private InvokeAdapter adapter;
    private final Gson gson = new Gson();
    private List<TodoBox> todoBoxes;
    private Set<String> currentHealthStates;
    private Set<String> currentMoods;
    private Set<String> drawnTaskIds;  // 添加已抽取任务的ID集合
    private Map<String, Map<String, Object>> taskMap;  // 添加 taskMap
    private String currentNetworkType = null;  // 添加当前网络状态
    private String currentCityType = null;  // 添加当前城市类型
    private String currentLocationType = null;  // 添加当前地点类型

    public View onCreateView(@NonNull LayoutInflater inflater,
                           ViewGroup container, Bundle savedInstanceState) {
        InvokeViewModel invokeViewModel =
                new ViewModelProvider(this).get(InvokeViewModel.class);

        binding = FragmentInvokeBinding.inflate(inflater, container, false);
        View root = binding.getRoot();

        // 初始化状态集合
        currentHealthStates = new HashSet<>();
        currentMoods = new HashSet<>();
        drawnTaskIds = new HashSet<>();  // 初始化已抽取任务集合

        // 设置更新状态按钮
        binding.btnUpdateState.setOnClickListener(v -> updateState());
        
        // 设置检查任务按钮
        binding.btnCheckTasks.setOnClickListener(v -> checkAndRemoveInvalidTasks());

        // 设置网络状态按钮
        binding.btnNoNetwork.setOnClickListener(v -> {
            currentNetworkType = "无网络";
            updateTodoBoxes();
        });

        binding.btnMobileData.setOnClickListener(v -> {
            currentNetworkType = "移动数据";
            updateTodoBoxes();
        });

        // 设置因地制宜按钮
        binding.btnLocationBased.setOnClickListener(v -> {
            loadLocationData();
        });

        RecyclerView recyclerView = binding.recyclerInvoke;
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));

        // 加载数据
        loadData();
        
        // 初始化适配器
        adapter = new InvokeAdapter(getContext(), new ArrayList<>(), taskMap);
        recyclerView.setAdapter(adapter);

        return root;
    }

    private void loadLocationData() {
        try {
            // 读取state.json文件
            File dataDir = new File(Environment.getExternalStorageDirectory(), "BingoBox/data");
            File stateFile = new File(dataDir, "state.json");
            
            if (!stateFile.exists()) {
                Toast.makeText(getContext(), "状态文件不存在", Toast.LENGTH_SHORT).show();
                return;
            }

            String json = new String(Files.readAllBytes(stateFile.toPath()), "UTF-8");
            Map<String, Object> stateData = gson.fromJson(json, new TypeToken<Map<String, Object>>(){}.getType());
            
            if (stateData == null) {
                Toast.makeText(getContext(), "状态数据为空", Toast.LENGTH_SHORT).show();
                return;
            }

            // 获取当前城市类型和地点类型
            currentCityType = (String) stateData.get("currentCityType");
            currentLocationType = (String) stateData.get("currentLocationType");

            // 更新适配器的城市类型
            adapter.updateCityType(currentCityType);

            // 更新任务盒显示
            updateTodoBoxes();
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(getContext(), "读取位置信息失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }

    private void updateTodoBoxes() {
        if (todoBoxes == null) return;

        List<TodoBox> filteredBoxes = new ArrayList<>();
        for (TodoBox todoBox : todoBoxes) {
            // 检查网络状态
            boolean networkMatch = currentNetworkType == null || 
                (todoBox.getNetworkTypes() != null && 
                 todoBox.getNetworkTypes().contains(currentNetworkType));

            // 检查地点类型
            boolean locationMatch = currentLocationType == null ||
                (todoBox.getLocationTypes() != null &&
                 todoBox.getLocationTypes().contains(currentLocationType));

            // 如果是通过因地制宜按钮触发的，只检查地点类型
            if (currentLocationType != null) {
                if (locationMatch) {
                    filteredBoxes.add(todoBox);
                }
            } else {
                // 如果是通过其他方式触发的，检查网络状态
                if (networkMatch) {
                    filteredBoxes.add(todoBox);
                }
            }
        }
        adapter.updateTodoBoxes(filteredBoxes);
    }

    private void loadData() {
        try {
            // 加载任务盒数据
            File dataDir = new File(Environment.getExternalStorageDirectory(), "BingoBox/data");
            File todoboxFile = new File(dataDir, "todobox.json");

            String json = new String(Files.readAllBytes(todoboxFile.toPath()), "UTF-8");
            Map<String, Object> data = gson.fromJson(json, new TypeToken<Map<String, Object>>(){}.getType());
            
            if (data == null || !data.containsKey("todoBoxes")) {
                Toast.makeText(getContext(), "任务盒数据格式错误", Toast.LENGTH_SHORT).show();
                todoBoxes = new ArrayList<>();
                return;
            }

            // 加载任务列表
            if (data.containsKey("tasks")) {
                List<Map<String, Object>> tasks = gson.fromJson(gson.toJson(data.get("tasks")), 
                    new TypeToken<List<Map<String, Object>>>(){}.getType());
                
                // 构建任务映射
                taskMap = new HashMap<>();
                for (Map<String, Object> task : tasks) {
                    if (task.containsKey("id")) {
                        taskMap.put(task.get("id").toString(), task);
                    }
                }
            }

            Type todoBoxType = new TypeToken<List<TodoBox>>(){}.getType();
            todoBoxes = gson.fromJson(gson.toJson(data.get("todoBoxes")), todoBoxType);
            
            // 更新适配器数据
            if (adapter != null) {
                updateTodoBoxes();
                adapter.updateTaskMap(taskMap);
            }
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(getContext(), "加载任务盒数据失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
            todoBoxes = new ArrayList<>();
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(getContext(), "解析任务盒数据失败", Toast.LENGTH_SHORT).show();
            todoBoxes = new ArrayList<>();
        }
    }

    private void updateState() {
        try {
            // 读取state.json文件
            File dataDir = new File(Environment.getExternalStorageDirectory(), "BingoBox/data");
            File stateFile = new File(dataDir, "state.json");
            
            String json = new String(Files.readAllBytes(stateFile.toPath()), "UTF-8");

            Map<String, Object> stateData = gson.fromJson(json, new TypeToken<Map<String, Object>>(){}.getType());
            
            // 更新当前状态
            currentHealthStates.clear();
            currentMoods.clear();
            
            // 解析健康状态
            if (stateData.containsKey("health")) {
                Object healthObj = stateData.get("health");
                
                if (healthObj instanceof String) {
                    currentHealthStates.add((String) healthObj);
                } else {
                    return;
                }
            }
            
            // 解析心情状态
            if (stateData.containsKey("mood")) {
                Object moodObj = stateData.get("mood");
                
                if (moodObj instanceof String) {
                    currentMoods.add((String) moodObj);
                } else {
                    return;
                }
            }

            // 检查状态是否都已设置
            if (currentHealthStates.isEmpty() || currentMoods.isEmpty()) {
                Toast.makeText(getContext(), "请先去状态页面设置好当前的健康和心情状态", Toast.LENGTH_LONG).show();
                return;
            }
                        
            // 筛选符合条件的任务盒
            List<TodoBox> filteredBoxes = new ArrayList<>();
            for (TodoBox box : todoBoxes) {
                boolean matchesHealth = box.getHealthStates() != null && 
                    box.getHealthStates().stream().anyMatch(currentHealthStates::contains);
                
                boolean matchesMood = box.getMoods() != null && 
                    box.getMoods().stream().anyMatch(currentMoods::contains);
                
                if (matchesHealth && matchesMood) {
                    filteredBoxes.add(box);
                }
            }
            
            // 更新UI
            if (filteredBoxes.isEmpty()) {
                Toast.makeText(getContext(), "暂无符合条件的任务盒", Toast.LENGTH_SHORT).show();
            }
            
            adapter.updateTodoBoxes(filteredBoxes);
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(getContext(), "读取状态文件失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(getContext(), "解析状态数据失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }

    // 添加日期格式化方法
    private String formatDate(long timestamp) {
        if (timestamp == 0) {
            return "无截止日期";
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日", Locale.getDefault());
        return sdf.format(new Date(timestamp));
    }

    
    private void checkAndRemoveInvalidTasks() {
        long currentTime = System.currentTimeMillis();
        int invalidCount = 0;

        try {
            // 先读取完整的数据
            File dataDir = new File(Environment.getExternalStorageDirectory(), "BingoBox/data");
            File todoboxFile = new File(dataDir, "todobox.json");
            
            String json = new String(Files.readAllBytes(todoboxFile.toPath()), "UTF-8");
            Map<String, Object> data = gson.fromJson(json, new TypeToken<Map<String, Object>>(){}.getType());

            // 遍历所有任务盒
            for (TodoBox todoBox : todoBoxes) {
                if (todoBox.getListData() != null && todoBox.getListData().getList() != null) {
                    List<TodoBox.TaskRef> taskRefs = todoBox.getListData().getList();
                    List<TodoBox.TaskRef> validTasks = new ArrayList<>();
                    
                    // 检查每个任务
                    for (TodoBox.TaskRef taskRef : taskRefs) {
                        Map<String, Object> task = taskMap.get(taskRef.getTaskId());
                        if (task != null) {
                            // 检查任务是否有效（未完成且未过期或永久）
                            boolean isCompleted = task.containsKey("completed") && 
                                                (Boolean) task.get("completed");
                            long deadline = task.containsKey("deadline") ? 
                                         ((Number) task.get("deadline")).longValue() : 0;
                            
                            boolean isValid = !isCompleted && 
                                            (deadline == 0 || deadline > currentTime);
                            
                            if (isValid) {
                                validTasks.add(taskRef);  // 只保留有效的任务
                            } else {
                                invalidCount++;
                            }
                        }
                    }

                    // 更新任务盒的任务列表
                    todoBox.getListData().setList(validTasks);
                }
            }

            // 更新数据中的 todoBoxes
            data.put("todoBoxes", todoBoxes);
            
            // 保存完整数据回文件
            String updatedJson = gson.toJson(data);
            Files.write(todoboxFile.toPath(), updatedJson.getBytes("UTF-8"));

            // 更新界面
            adapter.notifyDataSetChanged();

            // 显示结果
            if (invalidCount > 0) {
                Toast.makeText(getContext(), 
                    "已移除 " + invalidCount + " 个无效任务", 
                    Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(getContext(), 
                    "所有任务都是有效的", 
                    Toast.LENGTH_SHORT).show();
            }

        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(getContext(), "检查任务失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }

    
    // 显示状态管理对话框
    public void showViewStateDialog() {
        View dialogView = getLayoutInflater().inflate(R.layout.dialog_state_manage, null);

        // 获取视图引用
        TextView cityTypeText = dialogView.findViewById(R.id.text_city_type);
        TextView locationTypeText = dialogView.findViewById(R.id.text_location_type);
        TextView moodText = dialogView.findViewById(R.id.text_mood);
        TextView healthText = dialogView.findViewById(R.id.text_health);

        // NetworkSelector 会自动开始监听网络状态
        NetworkSelector networkSelector = dialogView.findViewById(R.id.network_selector);

        // 读取state.json文件
        File dataDir = new File(Environment.getExternalStorageDirectory(), "BingoBox/data");
        File stateFile = new File(dataDir, "state.json");

        try {
            if (stateFile.exists()) {
                String json = new String(Files.readAllBytes(stateFile.toPath()));
                Map<String, Object> stateData = gson.fromJson(json, new TypeToken<Map<String, Object>>() {
                }.getType());

                // 设置文本显示
                if (stateData.containsKey("currentCityType")) {
                    cityTypeText.setText(String.valueOf(stateData.get("currentCityType")));
                } else {
                    cityTypeText.setText("未设置");
                }

                if (stateData.containsKey("currentLocationType")) {
                    locationTypeText.setText(String.valueOf(stateData.get("currentLocationType")));
                } else {
                    locationTypeText.setText("未设置");
                }

                if (stateData.containsKey("mood")) {
                    moodText.setText(String.valueOf(stateData.get("mood")));
                } else {
                    moodText.setText("未设置");
                }

                if (stateData.containsKey("health")) {
                    healthText.setText(String.valueOf(stateData.get("health")));
                } else {
                    healthText.setText("未设置");
                }
            } else {
                // 如果文件不存在，显示默认值
                cityTypeText.setText("未设置");
                locationTypeText.setText("未设置");
                moodText.setText("未设置");
                healthText.setText("未设置");
            }
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(getContext(), "读取状态数据失败", Toast.LENGTH_SHORT).show();
            // 发生错误时显示默认值
            cityTypeText.setText("未设置");
            locationTypeText.setText("未设置");
            moodText.setText("未设置");
            healthText.setText("未设置");
        }

        new MaterialAlertDialogBuilder(requireContext())
                .setView(dialogView)
                .setPositiveButton("关闭", null)
                .show();
    }
}